package com.zhoug.common.utils.encrypt;

import android.util.Base64;

import com.zhoug.common.utils.LogUtils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 *
 * AES对称加密
 * AES加解密工具,不要用单例或成员变量,随用随创建对象
 *@see {@link AESHelper}
 * @Author 35574
 * @Date 2020/12/18
 * @Description
 * @deprecated
 */
@Deprecated
public class AesEncryptor {
    private static final String TAG = ">>>AesEncryptor";
    private static final boolean DEBUG = false;

    /**
     * 字符串编码方式
     */
    private Charset charset = StandardCharsets.UTF_8;

    /**
     * 编码和解码的flag
     * {@link Base64#DEFAULT} :最后有个换行符\n
     * {@link Base64#NO_PADDING} :这个参数是略去加密字符串最后的”=”
     * {@link Base64#NO_WRAP} :这个参数意思是略去所有的换行符
     */
    private int base64Flag = Base64.DEFAULT;
    /**
     * 算法/模式/填充
     */
    private String transformation = "AES/ECB/PKCS7Padding";
    // 密匙算法:AES加密
    private String algorithm = "AES";

    /**
     * 密匙
     * 支持128,192,256位 即16,24,32个字节
     */
    private String key;


    public AesEncryptor() {
    }


    /**
     * 创建加密器
     * 不用成员变量是为了支持并发,用成员变量时并发会引起bug(上次还没加密完成,有开始下次加密导致加密失败)
     * @return
     */
    private Cipher createEncryptCipher() throws Exception {
        if (DEBUG) {
            LogUtils.d(TAG, "创建加密器:key=" + key);
        }
        if(key==null){
            throw new IllegalArgumentException("key不能为null(支持128,192,256位)");
        }
        Cipher encryptCipher = Cipher.getInstance(transformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
        encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        return encryptCipher;
    }

    /**
     * 创建解密器
     */
    private Cipher createDecryptCipher() throws Exception {
        if (DEBUG) {
            LogUtils.d(TAG, "创建解密器:key=" + key);
        }
        if(key==null){
            throw new IllegalArgumentException("key不能为null(支持128,192,256位)");
        }
        Cipher decryptCipher = Cipher.getInstance(transformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
        decryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        return decryptCipher;

    }


    /**
     * 加密
     * 这是最基本的加密方法
     *
     * @param data 需要加密的字节数组
     * @return
     * @throws Exception
     */
    public byte[] encrypt(byte[] data) throws Exception {
        return createEncryptCipher().doFinal(data);
    }

    /**
     * 解密
     * 这是最基本的解密方法
     *
     * @param data 需要解密的字节数组
     * @return
     * @throws Exception
     */
    public byte[] decrypt(byte[] data) throws Exception {
        return createDecryptCipher().doFinal(data);
    }

    /**
     * 加密后编码为base64字符串
     *
     * @param data
     * @return
     * @throws Exception
     */
    public String encryptToString(byte[] data) throws Exception {
        if (data != null && data.length > 0) {
            byte[] encrypt = encrypt(data);
            if (encrypt != null && encrypt.length > 0) {
                return getBase64Utils().encodeToString(encrypt);
            }
        }
        return null;
    }

    /**
     * 加密后编码为base64字符串
     *
     * @param data
     * @return
     * @throws Exception
     */
    public String encryptToString(String data) throws Exception {
        if (data != null) {
            return encryptToString(getBase64Utils().getBytes(data));
        }
        return null;
    }

    /**
     * 解密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public String decryptToString(byte[] data) throws Exception {
        if (data != null && data.length > 0) {
            byte[] decrypt = decrypt(data);
            if (decrypt != null && decrypt.length > 0) {
                return new String(decrypt, 0, decrypt.length, charset);
            }
        }
        return null;
    }

    /**
     * 先用base64解码为字节数组再解密
     *
     * @param base64String
     * @return
     * @throws Exception
     */
    public String decryptToString(String base64String) throws Exception {
        if (base64String != null) {
            return decryptToString(getBase64Utils().decode(base64String));
        }
        return null;
    }


    /**
     * 设置密匙
     *
     * @param key
     */
    public AesEncryptor setKey(String key) {
        this.key = key;
        return this;
    }

    public String getKey() {
        return key;
    }

    /**
     * 算法/模式/填充
     *
     * @param transformation
     */
    public AesEncryptor setTransformation(String transformation) {
        if (transformation != null) {
            this.transformation = transformation;
        }
        return this;
    }

    public AesEncryptor setAlgorithm(String algorithm) {
        this.algorithm = algorithm;
        return this;
    }

    /**
     * 字符串编码方式
     * @param charset
     */
    public AesEncryptor setCharSet(Charset charset) {
        this.charset = charset;
        return this;
    }

    /**
     * Base64编码flag
     * @param base64Flag
     */
    public AesEncryptor setBase64Flag(int base64Flag) {
        this.base64Flag = base64Flag;
        return this;
    }

    private Base64Utils getBase64Utils() {
        return new Base64Utils(charset, base64Flag);
    }





}
